import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/widgets/bottom_sheet/date_time_select_bottom_sheet.dart';
import 'package:r_datetime_picker/r_datetime_picker.dart';

mixin SalaryDateSelectMixin<T> on BaseProvider<T> {
  DateTime from;
  DateTime to;

  List<String> datePopList = [];

  String currentSelectDatePop;

  @override
  void initState() {
    initChangeDatePop();
    super.initState();
  }

  void initChangeDatePop() {
    DateTime financialDate = DateTime.parse(Config.currentFY.startDate);
    int months = 12;
    datePopList.add(S.current.custom);
    for (int i = 1; i <= months; i++) {
      DateTime month = DateTime(financialDate.year, i, 1);
      datePopList.add(DateTimeUtils.formatDateTimeMMMYYYY(month));
    }

    if (currentSelectDatePop == null) {
      DateTime now = DateTime.now();
      currentSelectDatePop = datePopList[now.month - 1];
    }

    if (from == null && to == null) onChangeDatePop();
  }

  void onRequestRefresh();

  void onChangeDate(String value) {
    if (currentSelectDatePop == value) return;
    currentSelectDatePop = value;
    onChangeDatePop();
    update();
    if (currentSelectDatePop != S.current.custom) {
      onRequestRefresh();
    }
  }

  void onSelectFrom() {
    if (currentSelectDatePop != S.current.custom) return;
    obtainContext?.call((context) async {
      final result =
          await showDateTimeSelectBottomSheet(context, S.current.from, from);
      if (result != null) {
        if (to != null) {
          if (to.isAfter(result)) {
            from = result;
          } else {
            from = to;
          }
        } else {
          from = result;
        }
        update();
        checkFromToDateTimeRefresh();
      }
    });
  }

  void onSelectTo() {
    if (currentSelectDatePop != S.current.custom) return;
    obtainContext?.call((context) async {
      final result = await showDateTimeSelectBottomSheet(
          context, S.current.to, to ?? from?.add(Duration(days: 1)));
      if (result != null) {
        if (from != null) {
          if (from.isBefore(result)) {
            to = result;
          } else {
            to = from;
          }
        } else {
          to = result;
        }
        update();
        checkFromToDateTimeRefresh();
      }
    });
  }

  void checkFromToDateTimeRefresh() {
    if (from == null || to == null) return;
    onRequestRefresh();
  }

  void _onMonth(DateTime now) {
    int year = now.year;
    int month = now.month;
    final monthStart = DateTime(year, month, 1);
    final monthEnd =
        DateTime(year, month, RDatetimeUtils.getDaysInMonth(year, month));
    from = monthStart;
    to = monthEnd;
  }

  void _onCustom() {
    from = null;
    to = null;
  }

  void onChangeDatePop() {
    int index = datePopList.indexOf(currentSelectDatePop);

    if (currentSelectDatePop == S.current.custom) {
      _onCustom();
    } else {
      DateTime financialDate = DateTime.parse(Config.currentFY.startDate);
      final now = DateTime(financialDate.year, index);
      _onMonth(now);
    }
  }
}
